package com.example.basic.web.service.transTask.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.basic.core.foreignData.ForeignDataInParam;
import com.example.basic.core.foreignData.HoistDataInParam;
import com.example.basic.exception.ServiceException;
import com.example.basic.utils.HttpUtils;
import com.example.basic.utils.IdUtils;
import com.example.basic.utils.StringUtils;
import com.example.basic.web.enums.DeviceAddressEnum;
import com.example.basic.web.enums.DeviceStatusEnum;
import com.example.basic.web.enums.InstructStatusEnum;
import com.example.basic.web.mapper.device.DeviceMapper;
import com.example.basic.web.mapper.newly.*;
import com.example.basic.web.model.binding.BindingInfo;
import com.example.basic.web.model.device.Device;
import com.example.basic.web.model.newly.*;
import com.example.basic.web.model.terminal.TerminalRecord;
import com.example.basic.web.request.InterveneTaskRequest;
import com.example.basic.web.response.TaskRemainsResponse;
import com.example.basic.web.service.binding.BindingInfoService;
import com.example.basic.web.service.common.CommonService;
import com.example.basic.web.service.device.DeviceService;
import com.example.basic.web.service.stretcher.StretcherService;
import com.example.basic.web.service.terminal.TerminalRecordService;
import com.example.basic.web.service.transTask.TransTaskService;
import com.example.basic.web.webSocket.WebSocketServerUtil;
import org.checkerframework.checker.units.qual.A;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.example.basic.web.service.newly.impl.SysPdaFlowServiceImpl.*;


@Service
public class TransTaskServiceImpl implements TransTaskService {

    @Resource
    private CommonService commonService;
    @Resource
    private TerminalRecordService terminalRecordService;

    @Resource
    private DeviceService deviceService;

    @Resource
    private BindingInfoService bindingInfoService;

    @Resource
    private HttpServletRequest request;

    @Resource
    private StretcherService stretcherService;

    @Autowired
    private SysFlowTaskMapper sysFlowTaskMapper;

    @Autowired
    private SysPdaFlowMapper sysPdaFlowMapper;

    @Autowired
    private SysBacklogMapper sysBacklogMapper;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private SysExceptionalRecoveryMapper sysExceptionalRecoveryMapper;

    @Autowired
    private SysHandMoveMapper sysHandMoveMapper;


    private final static Logger logger = LoggerFactory.getLogger(TransTaskServiceImpl.class);

    @Override
    public Boolean sendTransTask(String documentNo) throws IOException {

        //获取未开始的任务
        TerminalRecord terminalRecord = terminalRecordService.queryNextStruct(documentNo);
        if (terminalRecord == null) {
            throw new ServiceException("未获取到需要执行的任务");
        }
        if (terminalRecord.getSortNo() > 1) {
            //更新任务起点
            TerminalRecord finishRecord = terminalRecordService.queryFinishRecord(documentNo);

            terminalRecord.setInstructStart(finishRecord.getInstructEnd());
        }

        String instructEnd = terminalRecord.getInstructEnd();
        if (StringUtils.emptyParams(terminalRecord.getDepotCode())) {

            Device unUseDockStation = new Device();

            if (terminalRecord.getOperType().contains("提升机")) {
                //获取空闲提升机
                unUseDockStation = deviceService.findUnUseDockStation(terminalRecord.getInstructEnd(), "4");
                if (unUseDockStation == null) {
                    //获取空闲接驳台
                    unUseDockStation = deviceService.findUnUseDockStation(terminalRecord.getInstructEnd(), "3");
                }
            } else {
                unUseDockStation = deviceService.findUnUseDockStation(instructEnd, "3");
            }

            if (unUseDockStation == null) {
                terminalRecord.setStatus(InstructStatusEnum.BLOCK.getType());
                terminalRecordService.update(terminalRecord);
                return false;
            } else {
                terminalRecord.setInstructEnd(unUseDockStation.getDevicePoint());

                //获取绑定信息
                BindingInfo bindingInfo = bindingInfoService.detail(terminalRecord.getRemainsCode());

                //更新设备为空闲状态
                deviceService.freeOrUse(bindingInfo.getDeviceCode());

                //更新绑定信息--与新设备绑定
                bindingInfo.setOriginDeviceCode(bindingInfo.getDeviceCode());
                bindingInfo.setDeviceCode(unUseDockStation.getDeviceCode());
                bindingInfoService.modify(bindingInfo);

                //更新设备为使用状态
                deviceService.freeOrUse(unUseDockStation.getDeviceCode());
            }

        }
        terminalRecord.setInstructTime(commonService.getDataBaseTime());
        terminalRecord.setStatus(InstructStatusEnum.IN_PROGRESS.getType());
        terminalRecord.setTaskRecordId(IdUtils.fastUUID());
        terminalRecordService.update(terminalRecord);

        //下发调度指令
        HttpUtils.sendPost(null, terminalRecord.getInstructStart(), terminalRecord.getInstructEnd(), terminalRecord.getTaskRecordId());

        return true;
    }

    @Override
    public Boolean executeBlockTask(String deviceCode) throws IOException {
        Device detail = deviceService.detail(deviceCode);

        //获取阻塞任务
        TerminalRecord terminalRecord = terminalRecordService.queryBlockTask(detail.getDeviceAddress());

        if (terminalRecord == null) {
            return false;
        }

        terminalRecord.setInstructTime(commonService.getDataBaseTime());
        terminalRecord.setInstructEnd(detail.getDevicePoint());
        terminalRecord.setStatus(InstructStatusEnum.IN_PROGRESS.getType());
        terminalRecord.setTaskRecordId(IdUtils.fastUUID());
        terminalRecordService.update(terminalRecord);

        //获取绑定信息
        BindingInfo bindingInfo = bindingInfoService.detail(terminalRecord.getRemainsCode());

        //更新设备为空闲状态
        deviceService.freeOrUse(bindingInfo.getDeviceCode());

        //更新绑定信息--与新设备绑定
        bindingInfo.setOriginDeviceCode(bindingInfo.getDeviceCode());
        bindingInfo.setDeviceCode(deviceCode);
        bindingInfoService.modify(bindingInfo);

        //更新设备为使用状态
        deviceService.freeOrUse(deviceCode);

        //下发调度指令
        HttpUtils.sendPost(null, terminalRecord.getInstructStart(), terminalRecord.getInstructEnd(), terminalRecord.getTaskRecordId());

        return true;
    }

    @Override
    public Boolean taskFinish(String documentNo) {

        //获取正在执行的任务
        TerminalRecord terminalRecord = terminalRecordService.queryInProgressTask(documentNo);

        if (terminalRecord != null) {
            //调用rds,任务完成
            try {
                HttpUtils.sendPost("terminate", terminalRecord.getInstructStart(), terminalRecord.getInstructEnd(), terminalRecord.getTaskRecordId());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            //获取绑定信息
            BindingInfo bindingInfo = bindingInfoService.detail(terminalRecord.getRemainsCode());

            //更新设备为空闲状态
            deviceService.freeOrUse(bindingInfo.getDeviceCode());

            //更新绑定信息--与设备解绑
            bindingInfo.setDeviceCode(null);
            bindingInfoService.modify(bindingInfo);
        }

        //获取所有未执行的任务
        List<TerminalRecord> terminalRecordList = terminalRecordService.queryWaitTask(documentNo);
        terminalRecordList.add(terminalRecord);
        terminalRecordList.forEach(record -> record.setStatus(InstructStatusEnum.CANCEL.getType()));
        terminalRecordService.batchUpdate(terminalRecordList);

        return true;
    }

    /**
     * 处理单个任务的完成
     *
     * @param foreignDataInParam 任务参数
     * @return 处理结果
     * @throws IOException 可能抛出的IO异常
     */
    public Boolean singleTaskFinish(ForeignDataInParam foreignDataInParam) throws IOException {

        SysFlowTask sysFlowTask = sysFlowTaskMapper.selectById(foreignDataInParam.getTaskRecordId());

        if (sysFlowTask == null) {
            throw new ServiceException("未获取到正在执行任务");
        }

        if (ObjectUtil.isEmpty(sysFlowTask.getFlowId())) {
            //不在流程内的
            if (sysFlowTask.getNowStage() == 13) {
                if (foreignDataInParam.getType().equals("1")) {
                    System.out.printf("担架板取货完成");
                    //代表取货完成 将开始状态置为已完成
                    sysFlowTask.setStartStatus(1);
                    sysFlowTask.setUpdateAt(new Date());
                    //同时将位置视为待机
                    Device start = deviceMapper.selectById(sysFlowTask.getStartPositionId());
                    start.setUpdateAt(new Date());
                    start.setStatus(DeviceStatusEnum.standby.getType());
                    deviceMapper.updateById(start);
                    sysFlowTaskMapper.updateById(sysFlowTask);
                } else if (foreignDataInParam.getType().equals("2")) {
                    //代表放货完成 将结束状态置为已完成
                    sysFlowTask.setEndStatus(1);
                    sysFlowTask.setUpdateAt(new Date());
                    //同时将位置视为待机
                    Device end = deviceMapper.selectById(sysFlowTask.getEndPositionId());
                    end.setUpdateAt(new Date());
                    end.setStatus(DeviceStatusEnum.standby.getType());
                    deviceMapper.updateById(end);

                    Device device = deviceMapper.selectById(sysFlowTask.getTargetPosition());
                    HttpUtils.sendPost(null, end.getDevicePoint(), device.getDevicePoint(), IdUtils.fastUUID());

//                    device.setStatus(DeviceStatusEnum.work.getType());
//                    device.setUpdateAt(new Date());
//                    deviceMapper.updateById(device);

                    sysFlowTaskMapper.updateById(sysFlowTask);
                }
            } else if (sysFlowTask.getNowStage() == 15) {
                //手动下发
                if (foreignDataInParam.getType().equals("1")) {
                    //取货完成 更改起点状态
                    Device device = deviceMapper.selectById(sysFlowTask.getStartPositionId());
                    device.setStatus(DeviceStatusEnum.standby.getType());
                    device.setUpdateAt(new Date());
                    deviceMapper.updateById(device);

                    sysFlowTask.setStartStatus(1);
                    sysFlowTask.setUpdateAt(new Date());
                    sysFlowTaskMapper.updateById(sysFlowTask);

                } else if (foreignDataInParam.getType().equals("2")) {
                    //代表放货完成 将结束状态置为已完成
//                    sysFlowTask.setEndStatus(1);
//                    sysFlowTask.setUpdateAt(new Date());
//                    sysFlowTaskMapper.updateById(sysFlowTask);
//                    //同时将终止位置设为占用
//                    Device end = deviceMapper.selectById(sysFlowTask.getEndPositionId());
//                    end.setUpdateAt(new Date());
//                    end.setStatus(DeviceStatusEnum.work.getType());
//                    deviceMapper.updateById(end);
                    handMoveEnd(sysFlowTask);
                }

            }
        } else {
            SysPdaFlow sysPdaFlow = sysPdaFlowMapper.selectById(sysFlowTask.getFlowId());
            if (sysPdaFlow == null) {
                throw new ServiceException("未获取到流程");
            }

            if (foreignDataInParam.getType().equals("1")) {
                //代表取货完成 将开始状态置为已完成
                sysFlowTask.setStartStatus(1);
                sysFlowTask.setUpdateAt(new Date());
                //同时将位置视为待机
                Device start = deviceMapper.selectById(sysFlowTask.getStartPositionId());
                start.setUpdateAt(new Date());
                start.setStatus(DeviceStatusEnum.standby.getType());
                deviceMapper.updateById(start);

                sysFlowTaskMapper.updateById(sysFlowTask);
//                sysPdaFlowMapper.updateById(sysPdaFlow);

            } else if (foreignDataInParam.getType().equals("2")) {
                //代表放货完成 将结束状态置为已完成
                sysFlowTask.setEndStatus(1);
                sysFlowTask.setUpdateAt(new Date());
                //如果终点位置为担架板库,那么需要将该流程的位置置空
                Device overDevice = deviceMapper.selectById(sysFlowTask.getEndPositionId());
                if (overDevice.getDeviceType().equals("11")){
                    sysPdaFlow.setPositionId(null);
                }else {
                    sysPdaFlow.setPositionId(sysFlowTask.getEndPositionId());
                }

//                sysPdaFlow.setPositionId(sysFlowTask.getEndPositionId());

                Device end = deviceMapper.selectById(sysFlowTask.getEndPositionId());
                end.setUpdateAt(new Date());
                deviceMapper.updateById(end);

                //判断阶段 往对应的用户发消息
                Integer nowStage = sysFlowTask.getNowStage();

                sysFlowTaskMapper.updateById(sysFlowTask);
                sysPdaFlowMapper.updateById(sysPdaFlow);

                switch (nowStage) {
                    case 0:

                        //往初次确认暂存区发消息 已到暂存区
                        addBacklog(sysPdaFlow.getId(), "308007ce-f0ca-4c11-8057-5703699c6e7e");
                        WebSocketServerUtil.sendInfo("来新任务了", "308007ce-f0ca-4c11-8057-5703699c6e7e");
                        break;

                    case 1:

                        //已到消毒渠
                        addBacklog(sysPdaFlow.getId(), "be1260df-639d-4599-a121-ec928f793c45");
                        WebSocketServerUtil.sendInfo("来新任务了", "be1260df-639d-4599-a121-ec928f793c45");
                        break;
                    case 2:
                        //已到spa
                        sysPdaFlow.setDisinfectStatus(FLOW_STATUS_SURE);
                        if (sysPdaFlow.getIsSpa().equals(FLOW_STATUS_YES)) {
                            //需要spa

                            //新增下一个spa阶段的待办,直接新
                            addBacklog(sysPdaFlow.getId(), "02c5ffff-15a0-4291-8581-00a2d08f232a");
                            WebSocketServerUtil.sendInfo("来新任务了", "02c5ffff-15a0-4291-8581-00a2d08f232a");
                        } else if (sysPdaFlow.getIsMake().equals(FLOW_STATUS_YES)) {
                            //需要化妆
                            //新增下一个化妆阶段的待办,直接新
                            addBacklog(sysPdaFlow.getId(), "2a503a42-17a8-4306-844f-8682475ebb7b");
                            WebSocketServerUtil.sendInfo("来新任务了", "2a503a42-17a8-4306-844f-8682475ebb7b");
                        } else {
                            //spa和化妆都没有的话,直接进入二次确认
                            addBacklog(sysPdaFlow.getId(), "0c3bd3cf-02c7-44fd-8ef6-4bca11a92d22");
                            WebSocketServerUtil.sendInfo("来新任务了", "0c3bd3cf-02c7-44fd-8ef6-4bca11a92d22");
                        }
                        break;
                    case 4:
                        //化妆已到
                        if (sysPdaFlow.getIsMake().equals(FLOW_STATUS_YES)) {
                            //需要化妆
                            //新增下一个化妆阶段的待办,直接新增到化妆
                            addBacklog(sysPdaFlow.getId(), "2a503a42-17a8-4306-844f-8682475ebb7b");
                            WebSocketServerUtil.sendInfo("来新消息了", "2a503a42-17a8-4306-844f-8682475ebb7b");
                        } else {
                            //spa和化妆都没有的话,直接进入二次确认
                            addBacklog(sysPdaFlow.getId(), "0c3bd3cf-02c7-44fd-8ef6-4bca11a92d22");
                            WebSocketServerUtil.sendInfo("来新任务了", "0c3bd3cf-02c7-44fd-8ef6-4bca11a92d22");
                        }
                        break;
                    case 6:
                        //已到二次确认区
                        addBacklog(sysPdaFlow.getId(), "0c3bd3cf-02c7-44fd-8ef6-4bca11a92d22");
                        WebSocketServerUtil.sendInfo("来新任务了", "0c3bd3cf-02c7-44fd-8ef6-4bca11a92d22");
                        break;
                    case 7:
                        //已到瞻仰去
                        if (sysPdaFlow.getIsAdmire().equals(FLOW_STATUS_YES)) {
                            //需要瞻仰
                            //新增下一个瞻仰阶段的待办,直接新增到瞻仰
                            addBacklog(sysPdaFlow.getId(), "f4668902-09c2-4e8b-b34b-2c09aa2a22d4");
                            WebSocketServerUtil.sendInfo("来新任务了", "f4668902-09c2-4e8b-b34b-2c09aa2a22d4");
                        } else {
                            //不需要瞻仰 直接进入火化
                            //新增下一个火化阶段的待办,直接新增到火化
                            addBacklog(sysPdaFlow.getId(), "e2c66174-f836-449e-b02c-fbdda899fccf");
                            WebSocketServerUtil.sendInfo("来新任务了", "e2c66174-f836-449e-b02c-fbdda899fccf");
                        }
                        break;
                    case 8:
                        //已到火化区
                        addBacklog(sysPdaFlow.getId(), "e2c66174-f836-449e-b02c-fbdda899fccf");
                        WebSocketServerUtil.sendInfo("来新任务了", "e2c66174-f836-449e-b02c-fbdda899fccf");
                        break;
                    case 9:
                        //火化已经确认 完成
//                sysPdaFlow.setNowStage(9);
//                sysPdaFlow.setFireStatus(FLOW_STATUS_SURE);
//                sysPdaFlow.setUpdateAt(new Date());
                        break;

                    case 10:
                        //到负一负二中转区 发送到火花的命令
                        Device device = deviceMapper.selectById(sysPdaFlow.getPositionId());

                        LambdaQueryWrapper<Device> deviceEnd = new LambdaQueryWrapper<>();
                        deviceEnd.eq(Device::getDeviceType, 7);
                        deviceEnd.eq(Device::getEnableFlag, 1);
                        deviceEnd.eq(Device::getStatus, 1);
//                        deviceEnd.orderByAsc(Device::getDeviceCode);
                        List<Device> devices = deviceMapper.selectList(deviceEnd);
                        try {
                            if (devices.isEmpty()) {
                                //如果没有找到空闲的火化 发送到火化前暂存区
                                LambdaQueryWrapper<Device> deviceLambdaQueryWrapper = new LambdaQueryWrapper<>();
                                deviceLambdaQueryWrapper.eq(Device::getDeviceType, 14);
                                deviceLambdaQueryWrapper.eq(Device::getEnableFlag, 1);
                                deviceLambdaQueryWrapper.eq(Device::getStatus, 1);
                                deviceLambdaQueryWrapper.orderByAsc(Device::getDeviceCode);
                                List<Device> cacheDevice = deviceMapper.selectList(deviceLambdaQueryWrapper);

                                if (cacheDevice.isEmpty()) {
                                    throw new ServiceException("暂无空闲的设备");
                                }
                                Device cache = cacheDevice.get(0);

                                String taskRecordId = IdUtils.fastUUID();
                                //将两台设备都置为忙碌
                                cache.setStatus(DeviceStatusEnum.work.getType());
                                cache.setUpdateAt(new Date());

                                deviceMapper.updateById(cache);

                                SysFlowTask task = new SysFlowTask();
                                task.setId(taskRecordId);
                                task.setFlowId(sysPdaFlow.getId());
                                task.setStartPositionId(sysPdaFlow.getPositionId());
                                task.setEndPositionId(cache.getId());
                                task.setStartStatus(0);
                                task.setEndStatus(0);
                                task.setCreateAt(new Date());
                                task.setUpdateAt(new Date());
                                //到暂存区的 当前状态0信息录入 1暂存区 2消毒 3 spa 4冰柜 5化妆 6二次信息确认 7瞻仰 8火化
                                task.setNowStage(18);
                                sysFlowTaskMapper.insert(task);

                                HttpUtils.sendPost(null, device.getDevicePoint(), cache.getDevicePoint(), taskRecordId);


                            } else {


                                Device endDevice = devices.get(0);
                                String taskRecordId = IdUtils.fastUUID();
                                //将两台设备都置为忙碌
                                endDevice.setStatus(DeviceStatusEnum.work.getType());
                                endDevice.setUpdateAt(new Date());

                                deviceMapper.updateById(endDevice);

                                SysFlowTask task = new SysFlowTask();
                                task.setId(taskRecordId);
                                task.setFlowId(sysPdaFlow.getId());
                                task.setStartPositionId(sysPdaFlow.getPositionId());
                                task.setEndPositionId(endDevice.getId());
                                task.setStartStatus(0);
                                task.setEndStatus(0);
                                task.setCreateAt(new Date());
                                task.setUpdateAt(new Date());
                                //到暂存区的 当前状态0信息录入 1暂存区 2消毒 3 spa 4冰柜 5化妆 6二次信息确认 7瞻仰 8火化
                                task.setNowStage(8);
                                sysFlowTaskMapper.insert(task);

                                HttpUtils.sendPost(null, device.getDevicePoint(), endDevice.getDevicePoint(), taskRecordId);

                            }
                        } catch (IOException e) {
                            throw new ServiceException("调度失败请联系管理员");
                        }
                        break;
                    case 11:
                        //到这证明已到中专提升机 下一步 从中转提升机到担架板中转
                        Device zzDevice = deviceMapper.selectById(sysPdaFlow.getPositionId());

                        LambdaQueryWrapper<Device> deviceLambdaQueryWrapper = new LambdaQueryWrapper<>();
                        deviceLambdaQueryWrapper.eq(Device::getDeviceType, 12);
                        deviceLambdaQueryWrapper.eq(Device::getEnableFlag, 1);
                        deviceLambdaQueryWrapper.eq(Device::getStatus, 1);
                        deviceLambdaQueryWrapper.orderByAsc(Device::getDeviceCode);
                        List<Device> djDevice = deviceMapper.selectList(deviceLambdaQueryWrapper);
                        if (djDevice.isEmpty()) {
                            throw new ServiceException("暂无空闲的设备");
                        }
                        Device device1 = djDevice.get(0);
                        try {

                            String taskRecordId = IdUtils.fastUUID();
                            //将两台设备都置为忙碌
                            device1.setStatus(DeviceStatusEnum.work.getType());
                            device1.setUpdateAt(new Date());

                            deviceMapper.updateById(device1);

                            SysFlowTask task = new SysFlowTask();
                            task.setId(taskRecordId);
                            task.setFlowId(sysPdaFlow.getId());
                            task.setStartPositionId(sysPdaFlow.getPositionId());
                            task.setEndPositionId(device1.getId());
                            task.setStartStatus(0);
                            task.setEndStatus(0);
                            task.setCreateAt(new Date());
                            task.setUpdateAt(new Date());
                            //到暂存区的 当前状态0信息录入 1暂存区 2消毒 3 spa 4冰柜 5化妆 6二次信息确认 7瞻仰 8火化
                            task.setNowStage(12);
                            sysFlowTaskMapper.insert(task);

                            HttpUtils.sendPost(null, zzDevice.getDevicePoint(), device1.getDevicePoint(), taskRecordId);
                        } catch (IOException e) {
                            throw new ServiceException("调度失败请联系管理员");
                        }
                        break;
                    case 14:
                        //已经送到担架板库
                        System.out.printf("担架板已入库，流程完毕");
                        //将担架板状态设为1，代表已在库
                        Device nowDevice = deviceMapper.selectById(sysPdaFlow.getPositionId());
                        nowDevice.setStatus("3");
                        nowDevice.setUpdateAt(new Date());
                        deviceMapper.updateById(nowDevice);

                        break;
                    case 12:
                        //到这里证明到担架板中转区
                        Device djzzDevice = deviceMapper.selectById(sysPdaFlow.getPositionId());

                        LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
                        queryWrapper.eq(Device::getDeviceType, 11);
                        queryWrapper.eq(Device::getEnableFlag, 1);
                        queryWrapper.eq(Device::getStatus, DeviceStatusEnum.standby.getType());
                        queryWrapper.orderByAsc(Device::getDeviceCode);
                        List<Device> deviceList = deviceMapper.selectList(queryWrapper);
                        if (deviceList.isEmpty()) {
                            throw new ServiceException("暂无空闲的设备");
                        }
                        Device device2 = deviceList.get(0);
                        try {

                            String taskRecordId = IdUtils.fastUUID();
                            //将两台设备都置为忙碌
                            device2.setStatus(DeviceStatusEnum.work.getType());
                            device2.setUpdateAt(new Date());

                            deviceMapper.updateById(device2);

                            SysFlowTask task = new SysFlowTask();
                            task.setId(taskRecordId);
                            task.setFlowId(sysPdaFlow.getId());
                            task.setStartPositionId(sysPdaFlow.getPositionId());
                            task.setEndPositionId(djzzDevice.getId());
                            task.setStartStatus(0);
                            task.setEndStatus(0);
                            task.setCreateAt(new Date());
                            task.setUpdateAt(new Date());
                            //到暂存区的 当前状态0信息录入 1暂存区 2消毒 3 spa 4冰柜 5化妆 6二次信息确认 7瞻仰 8火化
                            task.setNowStage(14);
                            sysFlowTaskMapper.insert(task);

                            HttpUtils.sendPost(null, djzzDevice.getDevicePoint(), device2.getDevicePoint(), taskRecordId);
                        } catch (IOException e) {
                            throw new ServiceException("调度失败请联系管理员");
                        }
                        break;

                    case 16:
                        //异常处理 只需要向目标用户发消息
                        LambdaQueryWrapper<SysExceptionalRecovery> recoveryLambdaQueryWrapper = new LambdaQueryWrapper<>();
                        recoveryLambdaQueryWrapper.eq(SysExceptionalRecovery::getFlowId, sysPdaFlow.getId());
                        recoveryLambdaQueryWrapper.eq(SysExceptionalRecovery::getTaskId, sysFlowTask.getId());
                        SysExceptionalRecovery sysExceptionalRecovery = sysExceptionalRecoveryMapper.selectOne(recoveryLambdaQueryWrapper);
                        if (ObjectUtils.isNotEmpty(sysExceptionalRecovery)) {
                            addBacklog(sysPdaFlow.getId(), sysExceptionalRecovery.getTargetUserId());
                            WebSocketServerUtil.sendInfo("来新任务了", sysExceptionalRecovery.getTargetUserId());
                        }
                    default:
                        throw new ServiceException("流程异常");
                }


            }

        }
        // 获取正在执行的任务
//        TerminalRecord terminalRecord = terminalRecordService.queryByTaskRecordId(foreignDataInParam.getTaskRecordId());
//
//        if (terminalRecord == null) {
//            throw new ServiceException("未获取到正在执行的任务" + foreignDataInParam.toString());
//        }
//
//        // 遗体中转处理逻辑
//        if (terminalRecord.getOperType().equals("遗体中转")) {
//            // 取货完成
//            if (foreignDataInParam.getType().equals("1")) {
//                return true;
//            } else {
//                // 执行取货任务
//                sendTransTask(terminalRecord.getDocumentNo());
//                return true;
//            }
//        }
//
//        // 担架板处理逻辑
//        if (terminalRecord.getOperType().contains("担架板")) {
//            // 取货完成
//            if ((terminalRecord.getOperType().contains("入库") || terminalRecord.getOperType().contains("出库"))
//                    && foreignDataInParam.getType().equals("1")) {
//                // 更新担架板库位状态
//                stretcherService.freeOrUse(terminalRecord.getDepotCode());
//                return true;
//            }
//
//            // 更新任务为已完成
//            if (foreignDataInParam.getType().equals("2")) {
//                updateTaskToFinished(terminalRecord);
//
//                // 获取设备信息并更新状态
//                freeStartDeviceAndExecuteBlockTask(terminalRecord);
//
//                // 开始执行下一任务
//                TerminalRecord nextRecord = terminalRecordService.queryNextStruct(terminalRecord.getDocumentNo());
//
//                // 获取暂存区接驳台，无空闲设备则阻塞任务
//                Device endDevice = deviceService.findUnUseDockStation(nextRecord.getInstructEnd(), "3");
//                if (endDevice == null) {
//                    blockNextTask(nextRecord);
//                    return true;
//                }
//
//                // 设置并下发下一任务
//                setupAndDispatchNextTask(terminalRecord, nextRecord, endDevice);
//            }
//            return true;
//        }
//
//        if(terminalRecord.getOperType().contains("换车")){
//            //取货完成
//            if(foreignDataInParam.getType().equals("1")){
//                //获取设备信息
//                Device device = deviceService.findByPoint(terminalRecord.getInstructStart());
//                //更新设备为空闲
//                deviceService.freeOrUse(device.getDeviceCode());
//                //进行阻塞任务
//                try {
//                    this.executeBlockTask(device.getDeviceCode());
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//            }
//            //更新任务为已完成
//            if(foreignDataInParam.getType().equals("2")){
//                terminalRecord.setStatus(InstructStatusEnum.FINISH.getType());
//                terminalRecordService.update(terminalRecord);
//            }
//            return true;
//
//        }
//
//        // 火化间处理逻辑（-1层）
//        if (terminalRecord.getOperType().contains("-1层")) {
//            // 放货完成
//            if (foreignDataInParam.getType().equals("2")) {
//                updateTaskToFinished(terminalRecord);
//                freeStartDeviceAndExecuteBlockTask(terminalRecord);
//
//                // 判断终点设备是否是提升机
//                Device endDevice = deviceService.findByPoint(terminalRecord.getInstructEnd());
//
//                // 开始执行下一任务
//                TerminalRecord nextRecord = terminalRecordService.queryNextStruct(terminalRecord.getDocumentNo());
//
//                // 获取下一节点空闲设备
//                Device beginDevice = null;
//
//                if("4".equals(endDevice.getDeviceType())){
//                    beginDevice = deviceService.findUnUseDockStation(DeviceAddressEnum.CREMATION.getType(), endDevice.getDeviceType());
//                }else if("3".equals(endDevice.getDeviceType())){
//                    nextRecord.setInstructStart(terminalRecord.getInstructEnd());
//                    nextRecord.setInstructTime(commonService.getDataBaseTime());
//                    nextRecord.setStatus(InstructStatusEnum.IN_PROGRESS.getType());
//                    nextRecord.setTaskRecordId(IdUtils.fastUUID());
//                    terminalRecordService.update(nextRecord);
//
//                    // 下发调度指令
//                    HttpUtils.sendPost(null, nextRecord.getInstructStart(), nextRecord.getInstructEnd(), nextRecord.getTaskRecordId());
//
//                    return true;
//                }
//                if (beginDevice == null) {
//                    blockNextTask(nextRecord);
//                    return true;
//                }
//
//                // 设置并下发下一任务
//                setupAndDispatchNextTask(terminalRecord, nextRecord, beginDevice);
//            }
//            return true;
//        }
//
//        // 默认处理逻辑
//        String remainsCode = terminalRecord.getRemainsCode();
//        BindingInfo bindingInfo = bindingInfoService.detail(remainsCode);
//
//        // 取货完成
//        if (foreignDataInParam.getType().equals("1")) {
//            handlePickupCompleted(terminalRecord, foreignDataInParam, bindingInfo);
//        } else {
//            // 放货完成
//            handleDeliveryCompleted(terminalRecord, bindingInfo);
//        }
//
        return true;
    }


    public void addBacklog(String flowId, String userId) {
        SysBacklog sysBacklog = new SysBacklog();
        sysBacklog.setFlowId(flowId);
        sysBacklog.setSysUserId(userId);
        sysBacklog.setCreateAt(new Date());
        sysBacklog.setUpdateAt(new Date());
        sysBacklog.setStatus(FLOW_STATUS_NO);
        sysBacklog.setId(IdUtils.fastUUID());
        sysBacklogMapper.insert(sysBacklog);
    }

    /**
     * 更新任务状态为已完成
     *
     * @param record 终端记录
     */
    private void updateTaskToFinished(TerminalRecord record) {
        record.setStatus(InstructStatusEnum.FINISH.getType());
        record.setFinishTime(commonService.getDataBaseTime());
        terminalRecordService.update(record);
    }

    /**
     * 释放起始设备并执行阻塞任务
     *
     * @param record 终端记录
     */
    private void freeStartDeviceAndExecuteBlockTask(TerminalRecord record) throws IOException {
        // 获取设备信息
        Device device = deviceService.findByPoint(record.getInstructStart());
        // 更新设备为空闲
        deviceService.freeOrUse(device.getDeviceCode());
        // 执行阻塞任务
        this.executeBlockTask(device.getDeviceCode());
    }

    /**
     * 阻塞下一任务
     *
     * @param nextRecord 下一任务记录
     */
    private void blockNextTask(TerminalRecord nextRecord) {
        nextRecord.setStatus(InstructStatusEnum.BLOCK.getType());
        terminalRecordService.update(nextRecord);
    }

    /**
     * 设置并下发下一任务
     *
     * @param current   当前任务
     * @param next      下一任务
     * @param endDevice 结束设备
     */
    private void setupAndDispatchNextTask(TerminalRecord current, TerminalRecord next, Device endDevice) throws IOException {
        next.setInstructStart(current.getInstructEnd());
        next.setInstructEnd(endDevice.getDevicePoint());
        next.setInstructTime(commonService.getDataBaseTime());
        next.setStatus(InstructStatusEnum.IN_PROGRESS.getType());
        next.setTaskRecordId(IdUtils.fastUUID());
        terminalRecordService.update(next);

        // 下发调度指令
        HttpUtils.sendPost(null, next.getInstructStart(), next.getInstructEnd(), next.getTaskRecordId());
    }

    /**
     * 处理取货完成逻辑
     *
     * @param record      终端记录
     * @param param       输入参数
     * @param bindingInfo 绑定信息
     */
    private void handlePickupCompleted(TerminalRecord record, ForeignDataInParam param, BindingInfo bindingInfo) throws IOException {
        // 获取设备信息
        Device device = deviceService.findByPoint(param.getDeviceId());

        // 更新绑定信息
        bindingInfo.setAgvCode(device.getDeviceCode());
        bindingInfoService.modify(bindingInfo);

        // 更新患者绑定信息
        if (StringUtils.notEmptyParams(bindingInfo.getOriginDeviceCode())) {
            bindingInfo.setOriginDeviceCode(null);
            bindingInfoService.modify(bindingInfo);
        }

        // 释放起始设备并执行阻塞任务
        freeStartDeviceAndExecuteBlockTask(record);
    }

    /**
     * 处理放货完成逻辑
     *
     * @param record      终端记录
     * @param bindingInfo 绑定信息
     */
    private void handleDeliveryCompleted(TerminalRecord record, BindingInfo bindingInfo) {
        // 更新绑定信息
        bindingInfo.setAgvCode(null);
        bindingInfoService.modify(bindingInfo);

        // 更新任务状态
        updateTaskToFinished(record);
    }

    /**
     * 流程干预
     *
     * @param interveneTaskRequest
     * @return
     */
    @Override
    public Boolean interveneTask(InterveneTaskRequest interveneTaskRequest) {

        //单据编码
        String documentNo = interveneTaskRequest.getDocumentNo();

        //获取当前正在执行的任务
        TerminalRecord terminalRecord = terminalRecordService.queryInProgressTask(documentNo);

        if (terminalRecord != null) {
            throw new ServiceException("存在正在执行的任务,不允许进行流程干预");
        }

        //根据新流程创建任务流
        //参数校验
        if (interveneTaskRequest.getProcessType().equals("1")) {
            if (StringUtils.emptyParams(interveneTaskRequest.getDepotCode(), interveneTaskRequest.getIsStaging())) {
                throw new ServiceException("请选择一项新流程");
            }
        } else if (interveneTaskRequest.getProcessType().equals("2")) {
            if (StringUtils.emptyParams(interveneTaskRequest.getAdmireCode(), interveneTaskRequest.getCremationRoom(), interveneTaskRequest.getSpecialHandle(), interveneTaskRequest.getIsStaging())) {
                throw new ServiceException("请选择一项新流程");
            }
        }

        //获取最新一条完成的任务
        TerminalRecord finishRecord = terminalRecordService.queryFinishRecord(documentNo);

        //将后续任务直接完成
        terminalRecordService.finishAllRecord(documentNo);

        //获取最大任务序号
        Integer maxSortNo = terminalRecordService.findMaxSortNo(documentNo);

        //新增任务流程
        List<TerminalRecord> terminalRecordList = new ArrayList<>();

        //开始点位
        String beginAddress = finishRecord.getInstructEnd();

        Integer sortNo = maxSortNo + 1;

        //结束点位
        String endAddress = DeviceAddressEnum.STAGING_AREA.getType();

        terminalRecord = new TerminalRecord();

        if (StringUtils.notEmptyParams(interveneTaskRequest.getIsStaging()) && interveneTaskRequest.getIsStaging().equals("1")) {
            terminalRecord.setOperType("暂存区");
            terminalRecord.setRemainsCode(terminalRecord.getRemainsCode());
            terminalRecord.setInstructStart(beginAddress);
            terminalRecord.setInstructEnd(endAddress);
            terminalRecord.setStatus("0");
            terminalRecord.setSortNo(sortNo);
            terminalRecord.setDocumentNo(documentNo);
            terminalRecord.setInstructAddress(endAddress);
            terminalRecordList.add(terminalRecord);

            beginAddress = DeviceAddressEnum.STAGING_AREA.getType();
            sortNo += 1;
        }

        //直接出库
        if (interveneTaskRequest.getProcessType().equals("3")) {
            terminalRecordService.batchAdd(terminalRecordList);
            return true;
        }

        //是否需要特殊处理  todo 特殊处理
        if (StringUtils.notEmptyParams(interveneTaskRequest.getSpecialHandle())) {
            //单据状态
            String documnentStatus = "";
            documnentStatus = "2";
            //消毒
            endAddress = DeviceAddressEnum.DISINFECT.getType();
            documnentStatus = "3";
            //spa
            endAddress = DeviceAddressEnum.SPA.getType();

            terminalRecord = new TerminalRecord();
            terminalRecord.setOperType("特殊处理");
            terminalRecord.setRemainsCode(interveneTaskRequest.getRemainsCode());
            terminalRecord.setInstructStart(beginAddress);
            terminalRecord.setInstructEnd(endAddress);
            terminalRecord.setStatus("0");
            terminalRecord.setSortNo(sortNo);
            terminalRecord.setDocumentNo(documentNo);
            terminalRecord.setDocumentStatus(documnentStatus);
            terminalRecord.setInstructAddress(endAddress);
            terminalRecordList.add(terminalRecord);
            sortNo += 1;
            beginAddress = endAddress;
        }

        //是否需要瞻仰
        if (StringUtils.notEmptyParams(interveneTaskRequest.getAdmireCode())) {
            terminalRecord = new TerminalRecord();
            terminalRecord.setOperType("瞻仰厅提升机");
            terminalRecord.setRemainsCode(interveneTaskRequest.getRemainsCode());
            terminalRecord.setInstructStart(beginAddress);
            terminalRecord.setInstructEnd(DeviceAddressEnum.ADMIRE.getType());
            terminalRecord.setStatus("0");
            terminalRecord.setSortNo(sortNo);
            terminalRecord.setDocumentNo(documentNo);
            terminalRecord.setDocumentStatus("7");
            terminalRecord.setInstructAddress(DeviceAddressEnum.ADMIRE.getType());

            terminalRecordList.add(terminalRecord);

            beginAddress = DeviceAddressEnum.ADMIRE.getType();
            sortNo += 1;
        }

        //是否前往火化间
        if (StringUtils.notEmptyParams(interveneTaskRequest.getCremationRoom())) {
            terminalRecord = new TerminalRecord();
            terminalRecord.setOperType("运送遗体");
            terminalRecord.setRemainsCode(interveneTaskRequest.getRemainsCode());
            terminalRecord.setInstructStart(beginAddress);
            terminalRecord.setInstructEnd(DeviceAddressEnum.CREMATION.getType());
            terminalRecord.setStatus("0");
            terminalRecord.setSortNo(sortNo);
            terminalRecord.setDocumentNo(documentNo);
            terminalRecord.setInstructAddress(DeviceAddressEnum.CREMATION.getType());
            terminalRecordList.add(terminalRecord);
        }
        //是否前往库位
        if (StringUtils.notEmptyParams(interveneTaskRequest.getDepotCode())) {
            //接驳台->库位
            terminalRecord = new TerminalRecord();
            terminalRecord.setOperType("运送遗体");
            terminalRecord.setRemainsCode(interveneTaskRequest.getRemainsCode());
            terminalRecord.setInstructTime(commonService.getDataBaseTime());
            terminalRecord.setInstructStart(beginAddress);
            terminalRecord.setInstructEnd(interveneTaskRequest.getDepotCode());
            terminalRecord.setDepotCode(interveneTaskRequest.getDepotCode());
            terminalRecord.setStatus("0");
            terminalRecord.setOperPerson((String) request.getAttribute("userCode"));
            terminalRecord.setSortNo(sortNo);
            terminalRecord.setDocumentNo(documentNo);
            terminalRecord.setTaskRecordId(IdUtils.fastUUID());
            terminalRecordList.add(terminalRecord);
        }

        terminalRecordService.batchAdd(terminalRecordList);

        return true;
    }

    /**
     * 遗体信息列表
     *
     * @param searchParam
     * @param sex
     * @param cremation
     * @param page
     * @param size
     * @return
     */
    @Override
    public IPage<TaskRemainsResponse> remainsTaskList(String searchParam, String sex, String cremation, Integer page, Integer size) {

        Page<TaskRemainsResponse> queryPage = new Page<>();

        return terminalRecordService.remainsTaskList(queryPage, searchParam, sex, cremation);
    }

    /**
     * 更新提升机状态
     *
     * @param hoistDataInParam
     * @return
     */
    @Override
    public Boolean modifyHoistStatus(HoistDataInParam hoistDataInParam) {

        Device device = deviceService.findByPoint(hoistDataInParam.getDeviceId());

        //获取工作中的接驳台
        Device useDevice = deviceService.findWorkDevice(device.getDeviceAddress());
        if (useDevice == null) {
            return true;
        }
        //获取接驳台绑定遗体信息
        BindingInfo bindingInfo = bindingInfoService.findByDevice(device.getDeviceCode());

        TerminalRecord terminalRecord = new TerminalRecord();
        terminalRecord.setOperType("遗体中转");
        terminalRecord.setRemainsCode(bindingInfo.getRemainsCode());
        terminalRecord.setInstructTime(commonService.getDataBaseTime());
        terminalRecord.setInstructStart(useDevice.getDevicePoint());
        terminalRecord.setInstructEnd(device.getDevicePoint());
        terminalRecord.setStatus("0");
        terminalRecord.setOperPerson((String) request.getAttribute("userCode"));
        terminalRecord.setSortNo(1);
        terminalRecord.setTaskRecordId(IdUtils.fastUUID());
        terminalRecord.setDocumentNo(bindingInfo.getDocumentNo());
        try {
            HttpUtils.sendPost(null, terminalRecord.getInstructStart(), terminalRecord.getInstructEnd(), terminalRecord.getTaskRecordId());
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        }
        return true;
    }

    /**
     * 手动下发单个任务结束
     *
     * @param sysFlowTask
     */
    public void handMoveEnd(SysFlowTask sysFlowTask) {
        sysFlowTask.setEndStatus(1);
        sysFlowTask.setUpdateAt(new Date());
        sysFlowTaskMapper.updateById(sysFlowTask);
        if (ObjectUtils.isNotEmpty(sysFlowTask.getFlowId())) {
            SysPdaFlow sysPdaFlow = sysPdaFlowMapper.selectById(sysFlowTask.getFlowId());
            sysPdaFlow.setPositionId(sysFlowTask.getEndPositionId());
            sysPdaFlow.setUpdateAt(new Date());
            sysPdaFlowMapper.updateById(sysPdaFlow);
        }

        SysHandMove sysHandMove = sysHandMoveMapper.selectById(sysFlowTask.getHandMoveId());

        Device nowPosition = deviceMapper.selectById(sysFlowTask.getEndPositionId());

        Device endPosition = deviceMapper.selectById(sysHandMove.getEndPosition());


        if (!sysHandMove.getEndPosition().equals(sysFlowTask.getEndPositionId())) {
            //不是最后一步,还需要执行任务
            String uuid = IdUtils.fastUUID();

            SysFlowTask task = new SysFlowTask();
            task.setId(uuid);
            if (ObjectUtil.isNotEmpty(sysHandMove.getFlowId())) {
                task.setFlowId(sysHandMove.getFlowId());
            }
            task.setStartPositionId(nowPosition.getId());


            if (sysHandMove.getStage() == 1 && ObjectUtils.isNotEmpty(sysHandMove.getFirstTransferPosition())) {
                sysHandMove.setStage(2);
                if (ObjectUtils.isNotEmpty(sysHandMove.getSecondTransferPosition())) {
                    //TODO 需要发送任务 从中转位置1到中转位置2

                    LambdaQueryWrapper<Device> deviceLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    deviceLambdaQueryWrapper.eq(Device::getDeviceType, sysHandMove.getSecondTransferPosition());
                    deviceLambdaQueryWrapper.eq(Device::getStatus, DeviceStatusEnum.standby.getType());
                    List<Device> device = deviceMapper.selectList(deviceLambdaQueryWrapper);
                    if (ObjectUtils.isNotEmpty(device)) {
                        Device endDevice = device.get(0);
                        task.setEndPositionId(endDevice.getId());
                        endDevice.setStatus(DeviceStatusEnum.work.getType());
                        endDevice.setUpdateAt(new Date());
                        deviceMapper.updateById(endDevice);

                        sysHandMove.setStage(2);
                    }
                } else {
                    // TODO 从中转1到终点
                    task.setEndPositionId(endPosition.getId());
                }
            } else if (sysHandMove.getStage() == 2 && ObjectUtils.isNotEmpty(sysHandMove.getSecondTransferPosition())) {
                sysHandMove.setStage(3);
                //TODO 从中转2到终点
                task.setEndPositionId(endPosition.getId());
            }
            task.setStartStatus(0);
            task.setEndStatus(0);
            task.setCreateAt(new Date());
            task.setUpdateAt(new Date());
            task.setNowStage(15);
            task.setHandMoveId(sysFlowTask.getHandMoveId());
            sysFlowTaskMapper.insert(task);

            Device device = deviceMapper.selectById(task.getEndPositionId());
            device.setStatus(DeviceStatusEnum.work.getType());
            device.setUpdateAt(new Date());
            deviceMapper.updateById(device);


            try {
                HttpUtils.sendPost(null, nowPosition.getDevicePoint(), device.getDevicePoint(), uuid);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }

}
